package edu.yctc.delivery.config.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import edu.yctc.delivery.constant.PermissionResource;
import edu.yctc.delivery.constant.RestPath;
import edu.yctc.delivery.constant.StaticPath;
import edu.yctc.delivery.constant.TemplatePath;
import edu.yctc.delivery.utils.EnvUtil;

/**
 * 
 * @className ShiroConfig
 * @description Shiro配置类
 * @author zyj
 * @date 2020年1月28日
 *
 */
@Configuration
public class ShiroConfig {

    private static final String PREFIX = "/";
    // 内置过滤器
    /** 无需认证 */
    private static final String ANON = "anon";
    /** 需要认证 */
    private static final String AUTHC = "authc";

    @Autowired
    private EnvUtil envUtil;

    @Bean
    public ShiroFilterFactoryBean
        getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 添加Shiro内置过滤器
        Map<String, String> filterMap = new LinkedHashMap<String, String>();
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

        // 无需认证的页面
        filterMap.put(PREFIX + StaticPath.COMMON_ERROR, ANON);
        filterMap.put(PREFIX + TemplatePath.USER_LOGIN, ANON);
        filterMap.put(PREFIX + TemplatePath.FIND_UPDATE_PASSWORD, ANON);
        filterMap.put(PREFIX + TemplatePath.RIGISTER, ANON);
        filterMap.put(PREFIX + TemplatePath.NO_AUTHORIZATION, ANON);

        // TODO 上线时关闭
        if (envUtil.isOnline()) {
            // 需要登陆认证的页面
            filterMap.put(PREFIX + TemplatePath.USER_LOGIN_SUCCESS, AUTHC);
            filterMap.put(PREFIX + TemplatePath.USER_HOME, AUTHC);
            filterMap.put(PREFIX + TemplatePath.USER_UPDATE_PASSWORD, AUTHC);
            filterMap.put(PREFIX + TemplatePath.USER_UPDATE_PASSWORD_SUCCESS, AUTHC);
            filterMap.put(PREFIX + TemplatePath.USER_LOGOUT, AUTHC);
            filterMap.put(PREFIX + TemplatePath.USER_LOGOUT_SUCCESS, AUTHC);
            filterMap.put(PREFIX + TemplatePath.USER_UPDATE_MAIL_SUCCESS, AUTHC);

            // 需要权限资源的页面
            filterMap.put(PREFIX + TemplatePath.MANAGE_AUTHORIZATION, PermissionResource.AUTHORITY_MANAGEMENT);

            // rest请求拦截
            // 需要认证的请求
            filterMap.put(RestPath.SEND_MAIL, AUTHC);
            filterMap.put(RestPath.SEND_MAILFORUPDATEMAIL, AUTHC);
        }

        // 设置自定义的登录页面
        shiroFilterFactoryBean.setLoginUrl(PREFIX + TemplatePath.USER_LOGIN);
        // 设置自定义的未授权页面
        shiroFilterFactoryBean.setUnauthorizedUrl(PREFIX + TemplatePath.NO_AUTHORIZATION);
        return shiroFilterFactoryBean;
    }

    /**
     * 创建DefaultWebSecurityManager
     *
     * @param userRealm
     * @return
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    /**
     * 创建Realm
     *
     * @return
     */
    @Bean(name = "userRealm")
    public UserRealm getRealm() {
        UserRealm userRealm = new UserRealm();
        return userRealm;
    }

    /**
     * 配合ShiroDialect，用于thymeleaf和shiro标签配合使用
     *
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
}
